package com.apes.framework.plugin.esb.processor.idempotent;

import com.alibaba.fastjson.JSONObject;
import com.apes.framework.api.SpringManager;
import com.apes.framework.jpa.ApesBean;
import com.apes.framework.plugin.esb.api.EsbService;
import com.apes.framework.plugin.esb.api.Request;
import com.apes.framework.plugin.esb.processor.AbstractChainProcessor;
import com.apes.framework.util.CacheUtil;
import com.apes.framework.util.ReflectUtil;
import lombok.Data;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 功能：防重处理
 *
 * @author xul
 * @create 2019-11-21 15:39
 */
@Data
public class AntiHeavyProcessor<T extends Request, R> extends AbstractChainProcessor<T, R> {
    private String topic;
    private String keys; //幂等关键字，多个用‘,’分隔
    private String callbackEsbId;

    @Override
    public R process(T data) {
        R result;
        Map record = (Map) doProcess(data);
        Map values = new HashMap();
        String id = getId(record, values);
        AntiHeavy antiHeavy = SpringManager.getBean(AntiHeavyRepository.class).findOne(id);
        if (antiHeavy != null) {
            if (StringUtils.isEmpty(callbackEsbId)) {
                throw new RuntimeException(String.format("请不要重复提交！[%s]", id));
            }
            result = SpringManager.getBean(EsbService.class).invoke(callbackEsbId.trim(), values);
        } else {
            antiHeavy = new AntiHeavy();
            antiHeavy.setId(id);
            SpringManager.getBean(AntiHeavyRepository.class).save(antiHeavy);
            if (processor != null) {
                result = (R) processor.process(data);
            } else {
                result = (R) data.getData();
            }
        }
        return result;
    }

    @Override
    protected R doProcess(T data) {
        if (StringUtils.isEmpty(topic)) throw new RuntimeException("'topic'不允许为空！");
        if (StringUtils.isEmpty(keys)) throw new RuntimeException("'keys'不允许为空！");
        Object o = data.getData();
        if (o instanceof String) {
            o = JSONObject.parse((String) o);
        } else if (o instanceof ApesBean) {
            o = ReflectUtil.getMerge(o);
        }
        if (!(o instanceof Map)) {
            throw new RuntimeException("输入数据格式不正确。");
        }
        return (R) o;
    }

    private String getId(Map record, Map result) {
        List<String> values = new ArrayList<>();
        for (String key : keys.split(",")) {
            Object value = null;
            try {
                value = CacheUtil.getEngine().execute(key, record);
            } catch (Exception e) {
            }
            if (StringUtils.isEmpty(value)) throw new RuntimeException(String.format("当前主题：" + topic + ",关键字：%s 在传入的数据中不存在或值为空！", key));
            values.add(String.valueOf(value));
            result.put(key, value);
        }
        StringBuilder sb = new StringBuilder();
        sb.append(topic);
        for (String value : values) {
            sb.append(":").append(value);
        }
        return sb.toString();
    }

}
